#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <limits.h>
#include <sys/time.h>
#include <sys/types.h>

#include "log_pthread.h"

static pthread_attr_t attr;

static void* _noop_thd(void* arg)
{
    (void) arg;
    /* 调用格式化参数输入的写日志API的方法 */
    log_r(LOG_DEBUG, " create thread tid=%lu\n", pthread_self());
    return NULL;
}
static void* _thread_maker(void* arg)
{
    int to_produce = *(int*)arg;
    /* Sequentially create a number of threads that trivially exit. */
    while (to_produce) {
        pthread_t noop;
        pthread_create(&noop, &attr, &_noop_thd, NULL);
        pthread_join(noop, NULL);
        to_produce--;
    }
    return NULL;
}

int main(int argc, char **argv)
{
    /* 初始化日志缓冲区，并标识自己 */
    if (initLog("octopus_logger", 102400)) {
        fprintf(stderr, "can't initialize log buffer\n");
        exit(1);
    }

    /* 启动日志线程 */
    startLogThread();
    dbgprint("%s", " --------------start up--------------\n");    /* 使用程序调试打印专用函数 */
    log_r(LOG_NOTICE, " --------------start up--------------\n"); /* 最简单的调用写日志的API方法 */
    
    struct timeval start;
    struct timeval fin;
    int top, sub;
    pthread_t *thread;
    pthread_attr_init(&attr);
    /* Accept command line params.*/
    if (argc < 3) {
        log_r(LOG_NOTICE, " USAGE: <#thread-producers> <#produced>\n\n");
        stopLogThread();
        return 1;
    } else {
        top = atoi(argv[1]);
        sub = atoi(argv[2]);
        if (top < 1) top = 1;
        if (sub < 1) sub = 1;
        log_r(LOG_NOTICE, " Using %d parents and %d children for %d threads.\n",
                     top, sub, top * sub);
    }
    thread = calloc(top, sizeof(pthread_t));
    /* Start timer. */
    if (gettimeofday(&start, NULL)) {
        log_r(LOG_NOTICE, " Time of day failed.");
        abort();
    }
    int i = 0;
    for (; i < top; i++)
        pthread_create(&thread[i], &attr, &_thread_maker, &sub);
    for (i = 0; i < top; i++)
        pthread_join(thread[i], NULL);
    /* Stop timer. */
    if (gettimeofday(&fin, NULL)) {
        log_r(LOG_NOTICE, " Time of day failed at end.");
        abort();
    }
    /* Calculate the delta. */
    {
        int usec = fin.tv_usec - start.tv_usec;
        int sec  = fin.tv_sec  - start.tv_sec;
        if (usec < 0) {
            sec--;
            usec += 1000000;
        }
        log_r(LOG_NOTICE, " Time %d sec %d usec\n", sec, usec);
    }


    /* 停止日志线程 */
    stopLogThread();
    return 0;
}

